

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

typedef GridListViewBuilder = Widget Function(
    BuildContext context, int index, dynamic itemData);
typedef GridListViewCreatedCallback = void Function(
    GridListViewController controller);
typedef OnRefresh = void Function();
typedef OnLoading = void Function();

class GridListView extends StatefulWidget {
  final List dataList;
  final GridListViewBuilder itemView;
  final GridListViewCreatedCallback onGridListViewCreated;
  final OnRefresh? onRefresh;
  final OnLoading? onLoading;
  final bool enablePullDown;
  final bool enablePullUp;
  final int crossAxisCount;
  final double mainAxisSpacing;
  final double crossAxisSpacing;
  final double childAspectRatio;
  final Widget? noDataView;
  final bool shrinkWrap;
  final bool isScroll;
  final Widget? divider;
  final ScrollController? scrollController;

  const GridListView(
    this.dataList,
    this.itemView,
    this.onGridListViewCreated, {
    Key? key,
    this.crossAxisCount = 1, //横轴元素个数
    this.mainAxisSpacing = 10, //纵轴间距
    this.crossAxisSpacing = 10, //横轴间距
    this.childAspectRatio = 10, //子组件宽高长度比例
    this.enablePullDown = true,
    this.enablePullUp = true,
    this.onRefresh,
    this.onLoading,
    this.noDataView,
    this.shrinkWrap = true, //解决无限高度问题
    this.isScroll = true, //是否可以滑动
    this.divider, //分割线,crossAxisCount = 1,设置才有用
    this.scrollController, // 滚动控制器
  }) : super(key: key);

  @override
  _GridListViewState createState() => _GridListViewState();
}

class _GridListViewState extends State<GridListView> {
  RefreshController refreshController = RefreshController();

  bool isLoading = false;

  @override
  void dispose() {
    refreshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SmartRefresher(
      enablePullDown: widget.enablePullDown,
      enablePullUp: widget.enablePullUp,
      header: const WaterDropHeader(
        complete: Text("数据刷新"),
        failed: Text("没有数据了"),
      ),
      footer: CustomFooter(
        builder: (BuildContext context, LoadStatus? mode) {
          Widget body;
          if (mode == LoadStatus.idle) {
            body = const Text("上拉加载");
          } else if (mode == LoadStatus.loading) {
            body = const CupertinoActivityIndicator();
          } else if (mode == LoadStatus.failed) {
            body = const Text("加载失败,点击重试");
          } else if (mode == LoadStatus.canLoading) {
            body = const Text("松手,加载更多");
          } else {
            body = const Text("没有更多数据了");
          }
          return SizedBox(
            height: 55,
            child: Center(child: body),
          );
        },
      ),
      controller: refreshController,
      onRefresh: widget.onRefresh,
      onLoading: widget.onLoading,
      child: widget.dataList.isEmpty
          ? (widget.noDataView ??
              Container(
                alignment: Alignment.center,
                child: Text(isLoading ? '加载中...' : '没有数据'),
              ))
          : (widget.crossAxisCount == 1
              ? ListView.separated(
                  controller: widget.scrollController,
                  itemBuilder: (BuildContext context, int index) =>
                      widget.itemView(context, index, widget.dataList[index]),
                  separatorBuilder: (context, index) {
                    return widget.divider ?? Container();
                  },
                  itemCount: widget.dataList.length,
                  shrinkWrap: widget.shrinkWrap,
                  physics: widget.isScroll
                      ? null
                      : const NeverScrollableScrollPhysics(),
                )
              : GridView.builder(
                  controller: widget.scrollController,
                  itemBuilder: (BuildContext context, int index) =>
                      widget.itemView(context, index, widget.dataList[index]),
                  itemCount: widget.dataList.length,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: widget.crossAxisCount,
                    mainAxisSpacing: widget.mainAxisSpacing,
                    crossAxisSpacing: widget.crossAxisSpacing,
                    childAspectRatio: widget.childAspectRatio,
                  ),
                  shrinkWrap: widget.shrinkWrap,
                  physics: widget.isScroll
                      ? null
                      : const NeverScrollableScrollPhysics(),
                )),
    );
  }

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((mag) {
      widget.onGridListViewCreated(
          GridListViewController(refreshController, this));
    });
    super.initState();
  }

  setIsLoading(bool loadingState) {
    setState(() {
      isLoading = loadingState;
    });
  }
}

class GridListViewController {
  late RefreshController refreshController;
  late _GridListViewState viewState;

  GridListViewController(
      RefreshController controller, _GridListViewState state) {
    refreshController = controller;
    viewState = state;
    viewState.setIsLoading(true);
  }

  /// true 没有更多数据
  void onFinishLoading(bool isNoData) {
    if (isNoData) {
      refreshController.loadNoData();
    } else {
      refreshController.loadComplete();
    }
    viewState.setIsLoading(false);
  }

  onFinishRefresh() {
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    viewState.setIsLoading(false);
  }

  setIsLoading(bool loadingState) {
    viewState.setIsLoading(loadingState);
  }
}
